﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InterpreterTests.cs" company="dimamartovoi">
//   Apache License
//   Version 2.0, January 2004
//   http://www.apache.org/licenses
// </copyright>
// <summary>
//   Defines the InterpreterTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using ActorModel.Evolution;

using NUnit.Framework;

namespace Evolution.Tests
{
    /// <summary>
    ///     The interpreter tests.
    /// </summary>
    [TestFixture]
    public class InterpreterTests
    {
        #region Public Methods and Operators

        /// <summary>
        ///     The assign substring expression.
        /// </summary>
        [Test]
        public void AssignSubstringExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample24.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "001");
#endif
        }

        /// <summary>
        ///     The bitwise and expression.
        /// </summary>
        [Test]
        public void BitwiseAndExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample10.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "000000");
#endif
        }

        /// <summary>
        ///     The bitwise or expression.
        /// </summary>
        [Test]
        public void BitwiseOrExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample9.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "111111");
#endif
        }

        /// <summary>
        ///     The connector state expression.
        /// </summary>
        [Test]
        public void ConnectorStateExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample6.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func(string.Empty, new List<string> { "001", "010" });
            Assert.IsTrue(res.ElementAt(0) == "010");
#endif
        }

        /// <summary>
        ///     The declaration and assignment statements.
        /// </summary>
        [Test]
        public void DeclarationAndAssignmentStatements()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample2.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func(string.Empty, new List<string>());
            Assert.IsTrue(res.Count() == 1);
#endif
        }

        /// <summary>
        ///     The for loop statement.
        /// </summary>
        [Test]
        [Ignore("Incomplite yet.")]
        public void ForLoopStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample5.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func(string.Empty, new List<string>());
            Assert.IsTrue(res.ElementAt(0) == "001");
#endif
        }

        /// <summary>
        ///     The if statement.
        /// </summary>
        [Test]
        public void IfStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample3.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func(string.Empty, new List<string> { "0", "1" });
            Assert.IsTrue(res.ElementAt(0) == "011");
#endif
        }

        /// <summary>
        ///     The is substring expression.
        /// </summary>
        [Test]
        public void IsSubstringExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample18.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The less or equals expression.
        /// </summary>
        [Test]
        public void LessOrEqualsExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample26.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The max expression.
        /// </summary>
        [Test]
        public void MaxExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample22.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The min expression.
        /// </summary>
        [Test]
        public void MinExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample21.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The modulo expression.
        /// </summary>
        [Test]
        public void ModuloExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample23.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The more or equals expression.
        /// </summary>
        [Test]
        public void MoreOrEqualsExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample25.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The node state expression.
        /// </summary>
        [Test]
        public void NodeStateExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample7.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "000", "111" });
            Assert.IsTrue(res.ElementAt(0) == "010");
#endif
        }

        /// <summary>
        ///     The not expression.
        /// </summary>
        [Test]
        public void NotExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample8.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "100110");
#endif
        }

        /// <summary>
        ///     The o connector assign statement.
        /// </summary>
        [Test]
        public void OConnectorAssignStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample15.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(1) == "111");
#endif
        }

        /// <summary>
        ///     The o node assign statement.
        /// </summary>
        [Test]
        public void ONodeAssignStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample14.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "100");
#endif
        }

        /// <summary>
        ///     The return statement.
        /// </summary>
        [Test]
        public void ReturnStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample1.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("0", new List<string>(2) { "001", "100" });
            Assert.IsTrue(res.Count() == 3);
#endif
        }

        /// <summary>
        ///     The state concat expression.
        /// </summary>
        [Test]
        public void StateConcatExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample12.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "010010");
#endif
        }

        /// <summary>
        ///     The string comparasion expression.
        /// </summary>
        [Test]
        public void StringComparasionExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample13.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "11");
#endif
        }

        /// <summary>
        ///     The string not equals comparasion.
        /// </summary>
        [Test]
        public void StringNotEqualsComparasion()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample17.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "000");
#endif
        }

        /// <summary>
        ///     The substring expression.
        /// </summary>
        [Test]
        public void SubstringExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample16.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "11110");
#endif
        }

        /// <summary>
        ///     The to int expression.
        /// </summary>
        [Test]
        public void ToIntExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample20.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "1");
#endif
        }

        /// <summary>
        ///     The to string expression.
        /// </summary>
        [Test]
        public void ToStringExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample19.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("00", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "101");
#endif
        }

        /// <summary>
        ///     The while loop statement.
        /// </summary>
        [Test]
        public void WhileLoopStatement()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample4.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func(string.Empty, new List<string> { "01" });
            Assert.IsTrue(res.ElementAt(1) == "11");
#endif
        }

        /// <summary>
        ///     The xor expression.
        /// </summary>
        [Test]
        public void XorExpression()
        {
            var interpreter = new Interpreter();
            string codePath = Path.Combine(
                TestContext.CurrentContext.WorkDirectory, @"EvolutionTestSamples\sample11.evol");
            string code = File.ReadAllText(codePath);
            Func<string, IEnumerable<string>, IEnumerable<string>> func = interpreter.Interprete(code);
#if !DEBUG
            IEnumerable<string> res = func("010", new List<string> { "111", "000" });
            Assert.IsTrue(res.ElementAt(0) == "111111");
#endif
        }

        #endregion
    }
}